#!/usr/bin/env bash

set -euo pipefail

# ==============================================
# build_android_apk.sh
# Purpose: Fetch code and build Android APK with Unity on macOS/Linux
# 
# Usage:
#   build_android_apk.sh <DEBUG|RELEASE> <branch> <clean:true|false> <projectPath> <unityPath> [logFile]
# Arguments:
#   - buildType   : DEBUG or RELEASE
#   - branch      : Git branch name, e.g., master
#   - clean       : true/false, whether to clean caches and old artifacts
#   - projectPath : Unity project directory (contains Assets/Packages, etc.)
#   - unityPath   : Path to Unity executable (e.g., /Applications/Unity/Hub/Editor/2023.3.51f1c1/Unity.app/Contents/MacOS/Unity)
#   - logFile     : Optional, output path for Unity -logFile (omit the flag if empty)
# ==============================================

buildType=${1:-}
branch=${2:-}
clean=${3:-false}
projectPath=${4:-}
unity=${5:-}
logFile=${6:-}

log() {
  # shellcheck disable=SC2154
  echo "[BUILD] [$(date '+%Y-%m-%d %H:%M:%S')] $*"
}

if [[ "${buildType}" != "DEBUG" && "${buildType}" != "RELEASE" ]]; then
  log "Invalid parameter: buildType must be DEBUG or RELEASE"
  exit 1
fi

if [[ -z "${branch}" ]]; then
  log "Invalid parameter: branch must be specified"
  exit 1
fi

if [[ -z "${projectPath}" || -z "${unity}" ]]; then
  log "Invalid parameter: projectPath and unityPath are required"
  exit 1
fi

cd "${projectPath}"

# Update Code
log "Update Code Start"
if ! git checkout "${branch}"; then exit 1; fi
if ! git fetch origin; then exit 1; fi
if ! git pull; then exit 1; fi
# if you want hard reset:
# git reset --hard "origin/${branch}" || exit 1
log "Update Code Finish"

# Check Changed
log "Check Changed"
buildDir="${projectPath}/Build"
curr_buildId="${buildDir}/build_id_${buildType}.txt"
last_buildId="${buildDir}/build_id_${buildType}_last.txt"
destApk="${projectPath}/Build/Android/${buildType}.apk"
mkdir -p "${buildDir}"

git log -1 --format=%h "origin/${branch}" > "${curr_buildId}" || true

if [[ -f "${last_buildId}" && -f "${destApk}" ]]; then
  if cmp -s "${curr_buildId}" "${last_buildId}"; then
    log "APK exists and up to date; no build needed"
    exit 0
  else
    rm -f "${destApk}"
  fi
fi
log "End Check Changed"

if [[ "${clean}" == "true" ]]; then
  rm -rf "${projectPath}/Assets/StreamingAssets" || true
  rm -rf "${projectPath}/Build/Android/${buildType}" || true
fi

# Prebuild
log "Prebuild Start"
if [[ -n "${logFile}" ]]; then
  "${unity}" -buildTarget Android -batchmode -nographics -quit -projectPath "${projectPath}" -executeMethod BuildTool.BuildCommand.PreBuild -logFile "${logFile}" || exit 1
else
  "${unity}" -buildTarget Android -batchmode -nographics -quit -projectPath "${projectPath}" -executeMethod BuildTool.BuildCommand.PreBuild || exit 1
fi
log "Prebuild Finish"

# BuildApk
log "BuildApk Start"
if [[ -n "${logFile}" ]]; then
  "${unity}" -batchmode -nographics -quit -projectPath "${projectPath}" -executeMethod BuildTool.BuildCommand.BuildAPK -logFile "${logFile}" || exit 1
else
  "${unity}" -batchmode -nographics -quit -projectPath "${projectPath}" -executeMethod BuildTool.BuildCommand.BuildAPK || exit 1
fi
log "BuildApk Finish"

# Resolve srcApk generated by BuildAPK
apkSearchRoot="${projectPath}/Build/Android/${buildType}"
srcApk=""
if [[ -n "${SRC_APK:-}" ]]; then
  srcApk="${SRC_APK}"
else
  # newest apk in directory
  if command -v find >/dev/null 2>&1; then
    srcApk=$(find "${apkSearchRoot}" -type f -name "*.apk" 2>/dev/null | xargs ls -t 2>/dev/null | head -n 1 || true)
  fi
  if [[ -z "${srcApk}" ]]; then
    srcApk=$(ls -t "${apkSearchRoot}"/*.apk 2>/dev/null | head -n1 || true)
  fi
fi

if [[ -z "${srcApk}" || ! -f "${srcApk}" ]]; then
  log "APK not found at ${srcApk}"
  exit 1
fi

mkdir -p "${projectPath}/Build/Android"
cp -f "${srcApk}" "${destApk}"
cp -f "${curr_buildId}" "${last_buildId}"
log "APK Output => ${destApk}"
log "BuildAPK Finished"
